#ifndef _FIRE_SFX_H_
#define _FIRE_SFX_H_

#include "math/counter.h"
#include "math/ramp.h"
#include "ui/ui_sprite.h"
namespace vfx
{

class	CyclicFX
{
public:
	struct				CyclicPart
	{
		math::Vec2		Pos, Speed;
		float			SpawnTime, Duration;
		float			Rotation, RotSpeed;
		float			Size;
	};
	typedef	void		(*SpawnParticleCB)(CyclicPart* pPart, void* pData);
	
						CyclicFX(int MaxC);
						~CyclicFX();
	virtual void		Init(const std::string& Image);
	virtual void		Shutdown();
	virtual void		Tick(float dt);
	void				GenContinuous(float dt);
	void				ForceGen();
	int					GetPartC() { return m_ActiveC; };

	virtual void		Render(const math::Vec2& Offset, float Scale);
	virtual void		RenderDebug(const math::Vec2& Offset, float Scale);

	void				SetCreateCB(SpawnParticleCB pCB, void* pData) { m_pCB = pCB; m_pCBData = pData; };
	const math::Vec2&	GetPos() const { return	m_Pos; };
	void				SetPos(const math::Vec2& P) { m_Pos = P; };
	void				SetGravity(float f) { m_Gravity = f; };
	void				SetMaxTime(float f) { m_MaxTime = f; };
	math::ColorRamp&	GetColors() { return m_Colors; };
	void				SetDuration(float f) { m_Duration = f; };
	float				GetDuration() const { return m_Duration; };
	void				SetFuzzyBirth(float f) { m_FuzzyBirth = f; };



	// different initialization sets for common effect
	void				UseFireRamp();
	void				UseSmokeRamp();
	void				UseWaterRamp();
	void				UsePoisonRamp();

	// different generation sets for common effects. All assume the basic input is tge vfx::CyclicFX
	static void			GenBasicUpCB(CyclicPart* pObj, void* pData);
protected:
	SpawnParticleCB		m_pCB;
	void*				m_pCBData;
//	virtual CyclicPart*	SpawnParticle();		// override this if you want to customize behaviour

	math::Vec2			m_Pos;
	ui::UISprite		m_Sprite;
	math::Vec2			m_SpriteSize;
	math::ColorRamp		m_Colors;

	CyclicPart*			m_ParticleA;
	float				m_Gravity;
	int					m_MaxC;
	int					m_ActiveC;
	int					m_LastObj;
	float				m_MaxTime;
	float				m_LastGen;
	float				m_Duration;
	float				m_FuzzyBirth;
};

class					CyclicGravFX : public CyclicFX
{
public:
	CyclicGravFX (int MaxC) :CyclicFX(MaxC), m_Gravity(0, 9.8f), m_Floor(0), m_HasFloor(false) 
	{

	}
	~CyclicGravFX ()
	{

	}
	virtual void		Tick(float dt);

	void				SetGravity(const math::Vec2& v) { m_Gravity = v; };
	void				SetFloor(float Height, bool HasFloor) { m_Floor = Height; m_HasFloor = HasFloor; };
protected:
	math::Vec2			m_Gravity;
	float				m_Floor;
	bool				m_HasFloor;
};

// provide a version that fits into the generic system as well?
}

#endif //_FIRE_SFX_H_